package com.tianyuan.lims.dms;

import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.activerecord.generator.MetaBuilder;
import com.jfinal.plugin.activerecord.generator.TableMeta;
import com.jfinal.plugin.druid.DruidPlugin;
import com.tianyuan.lims.common.config.JfinalConfig;
import io.github.yedaxia.apidocs.ApiDoc;

import javax.sql.DataSource;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wyq
 */
public class _JFinalGenerator {
    public static DataSource getDataSource() {
        DruidPlugin druidPlugin = JfinalConfig.createDruidPlugin();
        druidPlugin.start();
        return druidPlugin.getDataSource();
    }

    private static String[] getExcTab(String preName) {
        String sql = "SELECT table_name from information_schema.tables WHERE table_name LIKE '" + preName + "%'";
        List<String> list = new ArrayList<String>();
        Connection conn = null;
        try {
            conn = getDataSource().getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                list.add(rs.getString(1));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        String[] s = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            s[i] = list.get(i);
        }
        return s;
    }


    public static void main(String[] args) {
        // base model 所使用的包名
        String baseModelPackageName = "com.tianyuan.lims";
        // base model 文件保存路径
        String baseModelOutputDir = PathKit.getWebRootPath() + "/src/main/test/com/tianyuan/lims/base";

        // model 所使用的包名 (MappingKit 默认使用的包名)
        String modelPackageName = "com.tianyuan.lims";
        // model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径)
        String modelOutputDir = baseModelOutputDir + "/..";

        // 创建生成器
        Generator generator = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
        // 设置数据库方言
        generator.setDialect(new MysqlDialect());
        // 设置是否生成链式 setter 方法
        generator.setGenerateChainSetter(false);
        // 添加不需要生成的表名
        generator.addExcludedTable(getExcTab("72crm_"));
        // 设置是否在 Model 中生成 dao 对象
        generator.setGenerateDaoInModel(true);
        // 设置是否生成字典文件
        generator.setGenerateDataDictionary(false);
        // 添加不需要生成的表名
        generator.addExcludedTable("72crm");
        // 设置需要被移除的表名前缀用于生成modelName。例如表名 "osc_user"，移除前缀 "osc_"后生成的model名为 "User"而非 OscUser
        generator.setRemovedTableNamePrefixes("72crm_");


        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("JFinal 代码生成 power by houzw");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(500, 200);
            frame.setLocationRelativeTo(null);
            Box verticalBox = Box.createVerticalBox();
            verticalBox.add(Box.createVerticalStrut(50));
            JPanel panel = new JPanel();
            JButton button1 = new JButton("生成实体(model)");
            button1.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    generator.generate();
                    JOptionPane.showMessageDialog(frame, "生成完毕！");
                }
            });
            panel.add(button1);
            JButton button2 = new JButton("生控制器(controller)");
            button2.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        // TODO 生成
                        String controllerPackageName = "com.tianyuan.lims.dms.controller";
                        String controllerOutputDir = PathKit.getWebRootPath() + "/src/main/test/com/tianyuan/lims/dms/controller";
                        generateControllers(modelPackageName, controllerPackageName, controllerOutputDir);
                        JOptionPane.showMessageDialog(frame, "生成完毕!");
                    } catch (IOException exception) {
                        exception.printStackTrace();
                    }
                }
            });
            panel.add(button2);
            //frame.getContentPane().add(panel, BorderLayout.CENTER);
            verticalBox.add(panel);
            frame.getContentPane().add(verticalBox, BorderLayout.CENTER);
            frame.setVisible(true);
        });

        // generator.
        // TODO 生成
        //

    }

    public static void generateControllers(String modelPackageName, String controllerPackageName, String outputDir) throws IOException {
        MetaBuilder metaBuilder = new MetaBuilder(getDataSource());
        List<TableMeta> tableMetas = metaBuilder.build();
        for (TableMeta tableMeta : tableMetas) {
            String modelClassName = tableMeta.modelName;
            String controllerClassName = modelClassName + "Controller";
            StringBuilder sb = new StringBuilder();
            sb.append("package ").append(controllerPackageName).append(";\n\n");
            sb.append("import com.jfinal.core.Controller;\n");
            sb.append("import io.github.yedaxia.apidocs.ApiDoc;\n");
            sb.append("import com.tianyuan.lims.utils.R;\n");
            sb.append("import ").append(modelPackageName).append(".").append(modelClassName).append(";\n\n");
            sb.append("public class ").append(controllerClassName).append(" extends Controller {\n");

            // Create 方法
            sb.append("    @ApiDoc(url = \"/"+modelClassName+"/save\", method = \"post\")\n");
            sb.append("    public void save() {\n");
            sb.append("        ").append(modelClassName).append(" model = getModel(").append(modelClassName).append(".class);\n");
            sb.append("        if (model.save()) {\n");
            sb.append("            renderJson(R.ok(\"保存成功\"));\n");
            sb.append("        } else {\n");
            sb.append("            renderJson(R.ok(\"保存失败\"));\n");
            sb.append("        }\n");
            sb.append("    }\n");

            // Read 方法
            sb.append("    @ApiDoc(url = \"/"+modelClassName+"/get\", method = \"post\")\n");
            sb.append("    public void get() {\n");
            sb.append("        int id = getParaToInt();\n");
            sb.append("        ").append(modelClassName).append(" model = ").append(modelClassName).append(".dao.findById(id);\n");
            sb.append("        if (model != null) {\n");
            sb.append("            renderJson(R.ok().put(\"data\", model));\n");
            sb.append("        } else {\n");
            sb.append("            renderJson(R.ok(\"未找到记录\"));\n");
            sb.append("        }\n");
            sb.append("    }\n");

            // Update 方法
            sb.append("    @ApiDoc(url = \"/"+modelClassName+"/update\", method = \"post\")\n");
            sb.append("    public void update() {\n");
            sb.append("        ").append(modelClassName).append(" model = getModel(").append(modelClassName).append(".class);\n");
            sb.append("        if (model.update()) {\n");
            sb.append("            renderJson(R.ok(\"更新成功\"));\n");
            sb.append("        } else {\n");
            sb.append("            renderJson(R.ok(\"更新失败\"));\n");
            sb.append("        }\n");
            sb.append("    }\n");

            // Delete 方法
            sb.append("    @ApiDoc(url = \"/"+modelClassName+"/delete\", method = \"post\")\n");
            sb.append("    public void delete() {\n");
            sb.append("        int id = getParaToInt();\n");
            sb.append("        if (").append(modelClassName).append(".dao.deleteById(id)) {\n");
            sb.append("            renderJson(R.ok(\"删除成功\"));\n");
            sb.append("        } else {\n");
            sb.append("            renderJson(R.ok(\"删除失败\"));\n");
            sb.append("        }\n");
            sb.append("    }\n");

            sb.append("}\n");


            File outputDirFile = new File(outputDir);
            if(!outputDirFile.exists()){
                outputDirFile.mkdirs();
            }
            File outputFile = new File(outputDir, controllerClassName + ".java");
            if(!outputFile.exists()){
                outputFile.createNewFile();
            }
            try (FileWriter writer = new FileWriter(outputFile)) {
                writer.write(sb.toString());
            }
            System.err.println("Controller class gen success: " + controllerClassName + "[ " + modelClassName + " ]");
        }
    }
}
